﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Extentions;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using TrainingReminderSystem.Dal;
using TrainingReminderSystem.Model;

namespace TrainingReminderSystem.Bll
{
    /// <summary>
    /// 逻辑层
    /// </summary>
    public partial class SysEmployeeBll : PcLoginedBll
    {
        /// <summary>
        /// 验证码Key
        /// </summary>
        private const string CaptchaKey = "Captcha";

        #region 登录/注销

        /// <summary>
        /// 登录
        /// 支持手机号和员工编号
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="pwd"></param>
        /// <param name="captchaText">验证码</param>
        /// <returns></returns>
        public AjaxResult<List<LoginInfo>> Login(string uid, string pwd, string captchaText)
        {
            var r = new AjaxResult<List<LoginInfo>>();
            if (string.IsNullOrEmpty(uid))
            {
                r.Message = LanguageHelper.GetString<SysEmployee>("uid");
                return r;
            }
            if (string.IsNullOrEmpty(pwd))
            {
                r.Message = LanguageHelper.GetString<SysEmployee>("pwd");
                return r;
            }

            if (SysConfig.NeedCaptcha)
            {
                if (string.IsNullOrEmpty(captchaText))
                {
                    r.Message = lan["captchaText"];
                    return r;
                }

                captchaText = captchaText.ToUpper();
                string captcha = CacheHelper.GetCache(CaptchaKey + Device) as string;
                if (captcha != captchaText)
                {
                    CacheHelper.RemoveCache(CaptchaKey + Device);
                    r.Message = lan["captchaError"];
                    return r;
                }
            }
            pwd = pwd.ToUpper();

            using var db = DbNoFilter;
            //帐号是在员工里找的
            r = LoginBase(m => m.SysEmployeePhone == uid || m.UserCode == uid, pwd, null, db);
            if (SysConfig.NeedCaptcha && r.Success)
            {
                CacheHelper.RemoveCache(CaptchaKey + Device);
            }
            return r;
        }

        /// <summary>
        /// 设置登录信息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="validateLoginOutTime">是否验证失效时间</param>
        /// <returns></returns>
        public AjaxResult<LoginInfo> LoginByToken(string token, bool validateLoginOutTime = false)
        {
            using (var db = DbNoFilter)
            {
                return SetCacheByToken(token, db, validateLoginOutTime);
            }
        }

        #region 登录辅助方法

        /// <summary>
        /// 登录基础方法
        /// </summary>
        /// <param name="where"></param>
        /// <param name="pwd">密码登录的记录日志,进行密码判断</param>
        /// <param name="token"></param>
        /// <param name="db"></param>
        /// <param name="withCache"></param>
        /// <returns></returns>
        internal AjaxResult<List<LoginInfo>> LoginBase(Expression<Func<SysEmployee, bool>> where, string pwd, string token, DbEntities db, bool withCache = true)
        {
            //是否是密码登录的,如果是,则要做日志记录的
            bool isPwdLogin = !string.IsNullOrEmpty(pwd);
            AjaxResult<List<LoginInfo>> r = new AjaxResult<List<LoginInfo>>();
            IQueryable<SysEmployee> sysEmployeeListTemp = GetSysEmployeeListDb(where, db);
            if (sysEmployeeListTemp.Any() == false)
            {
                r.Message = LanguageHelper.GetString<SysEmployee>("notExist");
                return r;
            }
            string errorKey = null;
            List<SysEmployee> listDb = sysEmployeeListTemp.ToList();
            foreach (SysEmployee item in listDb)
            {
                if (isPwdLogin)
                {
                    if (string.IsNullOrEmpty(item.SysOperator.LoginPwd))
                    {
                        item.SysOperator.LoginPwd = DEncryptHelper.MakeMd5("123456");
                    }
                    if (item.SysOperator.LoginPwd != pwd)
                    {
                        errorKey = "pwdError";
                        continue;
                    }
                }

                errorKey = item.ValidateLogin();
                if (!string.IsNullOrEmpty(errorKey)) continue;
                //成功了的
                errorKey = null;
                break;
            }
            if (!string.IsNullOrEmpty(errorKey))
            {
                r.Message = LanguageHelper.GetString<SysEmployee>(errorKey);
                return r;
            }
            //以上面循环的提示逻辑做为筛选,筛选正常的数据集合
            Func<SysEmployee, bool> validateLoginWhere = SysEmployee.GetValidateLoginWhere();
            listDb = listDb.Where(validateLoginWhere).ToList();
            if (isPwdLogin)
            {
                Func<SysEmployee, bool> validateLoginPwdWhere = SysEmployee.GetValidateLoginPwdWhere(pwd);
                listDb = listDb.Where(validateLoginPwdWhere).ToList();
            }
            if (listDb.Count == 0)
            {
                r.Message = LanguageHelper.GetString<SysEmployee>("logicError");
                return r;
            }
            //带密码的,就是登录了的
            if (isPwdLogin)
            {
                string error = AddLog(db, listDb[0], EnumLogType.登录);
                if (!string.IsNullOrEmpty(error))
                {
                    r.Message = error;
                    r.Success = false;
                    return r;
                }
            }
            List<LoginInfo> listResult = new List<LoginInfo>();
            //如果有多个员工信息
            foreach (SysEmployee employee in listDb)
            {
                if (string.IsNullOrEmpty(token))
                {
                    token = CreateToken(employee);
                }
                //设置权限和员工信息缓存
                AjaxResult<LoginInfo> temp = SetCacheByToken(token, db, false, employee, withCache);
                if (temp.Success == false)
                {
                    r.Message = temp.Message;
                    return r;
                }
                listResult.Add(temp.Result);
                token = null;
            }
            db.SaveChanges();
            r.Success = true;
            r.Result = listResult;
            if (listResult.Count == 1)
            {
                SysEmployeeOpenIDBll.Bind(listResult[0].SysEmployeeID, db);
            }
            return r;
        }

        private IQueryable<SysEmployee> GetSysEmployeeListDb(Expression<Func<SysEmployee, bool>> where, DbEntities db)
        {
            var listTemp = db.SysEmployee.AsNoTracking().Include(m => m.SysOperator)
                .Include(m => m.SysRolePostEmployeeRelation)
                .Include(m => m.SysEmployeeStoreRelation)
                .ThenInclude(m => m.SysStore);
            var list = listTemp.Where(where);
            return list;
        }

        private string CreateToken(SysEmployee employee)
        {
            string loginUidTemp = !string.IsNullOrEmpty(employee.SysEmployeePhone)
                ? employee.SysEmployeePhone
                : employee.UserCode;
            string tokenInfo =
                $"{employee.SysEmployeeID}{TokenSplit}{employee.GetCurrentStore().SysStoreID}{TokenSplit}{(int)SysConfig.EnumRunProject}{TokenSplit}{loginUidTemp}{TokenSplit}{PcTokenKey}{TokenSplit}{DateTime.Now.ExToNormal()}";
            var r = employee.SysEmployeeID + TokenSplit + DEncryptHelper.Encrypt(tokenInfo);
            return r;
        }

        /// <summary>
        /// 设置缓存信息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="db"></param>
        /// <param name="validateLoginOutTime">是否验证失效时间</param>
        /// <param name="employee"></param>
        /// <returns></returns>
        private AjaxResult<LoginInfo> SetCacheByToken(string token, DbEntities db, bool validateLoginOutTime, SysEmployee employee = null, bool withCache = true)
        {
            var r = new AjaxResult<LoginInfo>();
            if (string.IsNullOrEmpty(token))
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            //有token解析他,他有具体是某一个帐号的
            var tempArray = token.Split(TokenSplit);
            var encrypt = token.Length > 1 ? tempArray[1] : null;
            if (string.IsNullOrEmpty(encrypt))
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            string val = DEncryptHelper.Decrypt(encrypt);
            if (string.IsNullOrEmpty(val))
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            var arr = val.Split(TokenSplit);
            if (arr.Length < 6)
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            int id = arr[0].ExToInt32();
            if (id <= 0)
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            if (tempArray[0].ExToInt32() != id)
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            //店铺ID
            int sysStoreID = arr[1].ExToInt32();
            if (sysStoreID <= 0)
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenError");
                return r;
            }
            //最后一个是时间
            DateTime dt = arr[arr.Length - 1].ExToDateTime();//arr[^1]最后一个的最新写法
            if (dt.Date != DateTime.Now.Date)
            {
                //解析失败的情况
                r.Message = LanguageHelper.GetString<SysEmployee>("tokenOverDate");
                return r;
            }
            if (validateLoginOutTime)
            {
                //店铺名称获取到的店铺ID
                var setting = SysSettingBll.GetModel(EnumSettingCode.PC端登录失效时间, sysStoreID, db);
                int timeOut = setting != null ? setting.Value.ExToInt32() : 0;
                if (timeOut > 0)
                {
                    int splitMin = (DateTime.Now - dt).Minutes;
                    if (splitMin >= timeOut)
                    {
                        return r;
                    }
                }
            }

            if (employee == null)
            {
                IQueryable<SysEmployee> sysEmployeeListTemp = GetSysEmployeeListDb(m => m.SysEmployeeID == id, db);
                employee = sysEmployeeListTemp.FirstOrDefault();
                if (employee == null)
                {
                    //解析失败的情况
                    r.Message = LanguageHelper.GetString<SysEmployee>("logicError");
                    return r;
                }
                string errorKey = employee.ValidateLogin();
                if (!string.IsNullOrEmpty(errorKey))
                {
                    r.Message = LanguageHelper.GetString<SysEmployee>(errorKey);
                    return r;
                }
            }

            SysStore store = employee.GetCurrentStore();
            var allSysPower = SysRolePostBll.AllSysPowerClone(db);
            var sysRolePostIDList = employee.SysRolePostEmployeeRelation.Select(m => m.SysRolePostID).ToList();
            List<SysPower> powerList = GetPowerList(sysRolePostIDList, employee.SysOperator.OperatorPower, allSysPower, db); //当前权限 没有关系的
            powerList = powerList.OrderBy(m => m.SysPowerID).ToList();
            employee.CurrentRights = powerList;
            if (withCache)
            {
                SetCurrentEmployee(token, employee);
            }

            LoginInfo result = new LoginInfo()
            {
                Token = token,
                UserName = employee.SysEmployeeName,
                UserHeader = employee.HeaderUrl,
                Route = LoginInfo.RouteClass.Build(powerList, powerList),
                ButtonPower = LoginInfo.ButtonPowerClass.Build(powerList, allSysPower),
                CanSeePhone = employee.CanSeePhone,
                IsAdminStore = store.IsAdminStore(),
                SysEmployeeID = employee.SysEmployeeID,
                SysStoreID = store.SysStoreID,
                IsMainStore = store.IsMainStore(),
                SysStoreName = store.SysStoreName,

                UserCode = employee.UserCode,

                IsDemo = employee.IsDemo,
                CreateDate = DateTime.Now
            };
            r.Success = true;
            r.Result = result;
            return r;
        }

        #endregion

        /// <summary>
        /// 注销登录
        /// </summary>
        /// <returns></returns>
        public AjaxResult<LoginOutResult> LoginOut()
        {
            string token = Token;
            if (string.IsNullOrEmpty(token)) return AjaxResult<LoginOutResult>.SuccessResult();
            int sysEmployeeID = CurrentEmployee?.SysEmployeeID ?? 0;
            int sysStoreID = CurrentStore?.SysStoreID ?? 0;

            //退出不注销微信
            //if (sysEmployeeID > 0)
            //{
            //    using var db = DbNoFilter;
            //    AddLog(db, new SysEmployee()
            //    {
            //        SysEmployeeID = sysEmployeeID
            //    }, EnumLogType.注销);
            //    db.SaveChanges();
            //    SysEmployeeOpenIDBll.Unbind(db);
            //}

            ClearCache(token);
            WebSocketBll.CloseThis(token);
            return AjaxResult<LoginOutResult>.SuccessResult(new LoginOutResult(sysEmployeeID, sysStoreID));
        }

        /// <summary>
        /// 注销结果
        /// </summary>
        public class LoginOutResult
        {
            public LoginOutResult(int sysEmployeeID, int sysStoreID)
            {
                SysEmployeeID = sysEmployeeID;
                SysStoreID = sysStoreID;
            }

            /// <summary>
            /// 员工ID
            /// </summary>
            public int SysEmployeeID { get; set; }

            /// <summary>
            /// 店铺ID
            /// </summary>
            public int SysStoreID { get; set; }
        }

        #region 权限相关

        private List<SysPower> GetPowerList(List<int> sysRolePostIDList, string operatorPower, List<SysPower> allSysPower,
            DbEntities db)
        {
            //角色权限
            List<int> listPowerData = db.SysRolePostPowerRelation
                .Where(m => sysRolePostIDList.Contains(m.SysRolePostID)).Select(m => m.SysPowerID)
                .ToList();
            if (!string.IsNullOrEmpty(operatorPower))
            {
                List<int> operatorPowerListTemp = operatorPower.Split(',').ToList().ExConvert(typeof(int));
                listPowerData.AddRange(operatorPowerListTemp);
            }

            listPowerData = listPowerData.Distinct().ToList(); //去除重复的权限ID

            List<SysPower> listPower = allSysPower.Where(m => listPowerData.Contains(m.SysPowerID)).ToList();
            //没有包含父级的,加入到里面去
            List<SysPower> notIn = new List<SysPower>();
            foreach (SysPower item in listPower)
            {
                NotInAdd(listPower, allSysPower, item, notIn);
            }

            listPower.AddRange(notIn);
            return listPower;
        }

        private void NotInAdd(List<SysPower> listPower, List<SysPower> allSysPower, SysPower item, List<SysPower> notIn)
        {
            if (item.ParentID == null) return;
            if (listPower.All(m => m.SysPowerID != item.ParentID))
            {
                var notInItem = allSysPower.FirstOrDefault(m => m.SysPowerID == item.ParentID);
                if (notInItem != null && notIn.All(m => m.SysPowerID != notInItem.SysPowerID))
                {
                    notIn.Add(notInItem);

                    NotInAdd(listPower, allSysPower, notInItem, notIn);
                }
            }
        }

        #endregion

        #endregion

        #region 修改密码

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="empID"></param>
        /// <param name="oldPass"></param>
        /// <param name="pass"></param>
        /// <param name="withOutOldPass">是否判断旧密码</param>
        /// <returns></returns>
        public AjaxResult<int> UpdatePwd(int empID, string oldPass, string pass, bool withOutOldPass = false)
        {
            if (CurrentEmployee != null && CurrentEmployee.IsDemo)
            {
                return AjaxResult<int>.ErrorResult("试用帐号不能更改密码");
            }
            oldPass = oldPass.ExTrim().ToUpper();
            pass = pass.ExTrim().ToUpper();
            var r = new AjaxResult<int>();
            if (oldPass == pass)
            {
                r.Message = LanguageHelper.GetString<SysEmployee>("pwdEqual");
                return r;
            }

            using (var db = Db)
            {
                var beforeModel = db.SysEmployee.Include(m => m.SysOperator)
                    .FirstOrDefault(m => m.SysEmployeeID == empID);
                var op = beforeModel?.SysOperator;
                if (beforeModel == null || op == null)
                {
                    r.Message = LanguageHelper.NoData;
                    return r;
                }
                if (withOutOldPass == false)
                {
                    if (op.LoginPwd != oldPass)
                    {
                        r.Message = "旧密码错误,不能更改";
                        return r;
                    }
                }

                op.LoginPwd = pass;
                string error = AddLog(db, beforeModel, EnumLogType.编辑);
                if (!string.IsNullOrEmpty(error))
                {
                    return AjaxResult<int>.ErrorResult(error);
                }
                db.SaveChanges();

                r.Message = LanguageHelper.Success;
                r.Success = true;
                return r;
            }
        }

        #endregion

        #region 我的信息

        /// <summary>
        /// 我的信息
        /// </summary>
        /// <returns></returns>
        public AjaxResult<dynamic> GetMyInfo()
        {
            var r = new AjaxResult<dynamic>();
            var current = CurrentEmployee;
            using (var db = Db)
            {
                r.Result = new
                {
                    current.SysEmployeeName,
                    current.SysEmployeePhone,
                    current.HeaderUrl,
                    current.UserCode,
                    LastLoginDateTime = db.SysOperateLog.OrderByDescending(m => m.ID).Where(m => m.EnumOperateLogType == EnumOperateLogType.登录 && m.SysEmployeeID == current.SysEmployeeID).Select(m => (DateTime?)m.CreateDate).FirstOrDefault(),
                    RoleNames = db.SysRolePostEmployeeRelation.Where(m => m.SysEmployeeID == current.SysEmployeeID).Select(m => m.SysRolePost.SysRolePostName).ToList().ExJoin()
                };
            }
            r.Success = true;
            return r;
        }

        /// <summary>
        /// 修改我的信息
        /// </summary>
        /// <param name="sysEmployeeName"></param>
        /// <param name="sysEmployeePhone"></param>
        /// <param name="headerUrl"></param>
        /// <returns></returns>
        public AjaxResult<dynamic> UpdateMyInfo(string sysEmployeeName, string sysEmployeePhone, string headerUrl)
        {
            if (CurrentEmployee != null && CurrentEmployee.IsDemo)
            {
                return AjaxResult<dynamic>.ErrorResult("试用帐号不能更改信息");
            }
            var r = new AjaxResult<dynamic>();
            sysEmployeeName = sysEmployeeName.ExTrim();
            if (string.IsNullOrEmpty(sysEmployeeName))
            {
                r.Message = "请输入员工姓名";
                return r;
            }

            sysEmployeePhone = sysEmployeePhone.ExTrim();
            if (string.IsNullOrEmpty(sysEmployeePhone))
            {
                r.Message = "请输入手机号";
                return r;
            }
            headerUrl = headerUrl.ExTrim();
            if (!string.IsNullOrEmpty(headerUrl))
            {
                headerUrl = Extentions.Base64Helper.SaveFileFromBase64(headerUrl);
            }

            var current = CurrentEmployee;
            using (var db = Db)
            {
                int sysStore = current.GetCurrentStore().SysStoreID;
                if (db.SysEmployee.Any(m =>
                    m.SysEmployeePhone == sysEmployeePhone && m.SysEmployeeID != current.SysEmployeeID && m.SysEmployeeStoreRelation.Any(n => n.SysStoreID == sysStore)))
                {
                    r.Message = "您输入的手机号已存在,请换个手机号";
                    return r;
                }

                var before = db.SysEmployee.FirstOrDefault(m => m.SysEmployeeID == current.SysEmployeeID);
                if (before == null)
                {
                    r.Message = LanguageHelper.NoData;
                    return r;
                }
                before.SysEmployeeName = sysEmployeeName;
                before.SysEmployeePhone = sysEmployeePhone;
                before.HeaderUrl = headerUrl;

                string error = AddLog(db, before, EnumLogType.编辑);
                if (!string.IsNullOrEmpty(error))
                {
                    return AjaxResult<dynamic>.ErrorResult(error);
                }
                db.SaveChanges();
                current.SysEmployeeName = sysEmployeeName;
                current.SysEmployeePhone = sysEmployeePhone;
                current.HeaderUrl = headerUrl;
                SetCurrentEmployee(current.Token, current);

                ClearCache(current.SysEmployeeID);

                r.Result = headerUrl;
                r.Message = LanguageHelper.Success;
                r.Success = true;
                r.Total = (int)EnumTotal.用户信息及权限重新加载;
                return r;
            }
        }

        #endregion

        #region 验证码相关

        /// <summary>
        /// 是否需要验证码
        /// </summary>
        /// <returns></returns>
        public AjaxResult<WebConfigInfo> GetNeedCaptcha()
        {
            WebConfigInfo result = new WebConfigInfo()
            {
                NeedCaptcha = SysConfig.NeedCaptcha,
                WebAppID = SysConfig.WxOpen.WebAppID
            };
            return AjaxResult<WebConfigInfo>.SuccessResult(result);
        }

        /// <summary>
        /// 网站基本配置
        /// </summary>
        public class WebConfigInfo
        {
            /// <summary>
            /// 是否需要验证码
            /// </summary>
            public bool NeedCaptcha { get; set; }

            /// <summary>
            /// 扫码登录的网站应用appid
            /// </summary>
            public string WebAppID { get; set; }
        }

        /// <summary>
        /// 创建验证码
        /// </summary>
        /// <returns></returns>
        public AjaxResult<string> CreateCaptcha()
        {
            if (SysConfig.NeedCaptcha) AjaxResult<string>.SuccessResult("");
            string code = CaptchaHelper.CreateRandom(SysConfig.CaptchaLength);
            string base64 = CaptchaHelper.CreateGraphicBase64(code);
            CacheHelper.SetAbsoluteCache(CaptchaKey + Device, code, 300);//5分钟
            return AjaxResult<string>.SuccessResult(base64);
        }

        #endregion
    }

    #region 登录成功返回信息

    /// <summary>
    /// 登录成功返回信息
    /// </summary>
    public class LoginInfo
    {
        #region 路由类 和 按钮权限类

        /// <summary>
        /// 路由类
        /// </summary>
        public class RouteClass
        {
            public class MetaClass
            {
                public string title { get; set; }

                public string remixIcon { get; set; }

                public string icon { get; set; }

                public bool affix { get; set; }

                /// <summary>
                /// {target:'_blank',badge:'New'}
                /// </summary>
                public string badge { get; set; }

                /// <summary>
                /// {target:'_blank',badge:'New'}
                /// </summary>
                public string target { get; set; }
            }

            public string path { get; set; }

            public string name { get; set; }

            public MetaClass meta { get; set; }

            public List<RouteClass> children { get; set; }

            /// <summary>
            /// 得到所有菜单
            /// </summary>
            /// <param name="powerList">筛选过了的</param>
            /// <param name="allPowerList">所有</param>
            /// <param name="isFirst"></param>
            /// <returns></returns>
            internal static List<RouteClass> Build(List<SysPower> powerList, List<SysPower> allPowerList, bool isFirst = true)
            {
                List<RouteClass> r = new List<RouteClass>();
                var list = powerList.Where(m => m.EnumPowerType == EnumPowerType.菜单).ToList();
                if (isFirst)
                {
                    list = list.Where(m => m.ParentID == null).ToList();
                }
                foreach (SysPower item in list)
                {
                    MetaClass jsonMeta = null;
                    if (!string.IsNullOrEmpty(item.Json))
                    {
                        jsonMeta = JsonHelper.DeserializeObject<MetaClass>(item.Json);
                    }

                    var children = allPowerList
                        .Where(m => m.EnumPowerType == EnumPowerType.菜单 && m.ParentID == item.SysPowerID).ToList();
                    RouteClass route = new RouteClass()
                    {
                        name = (isFirst ? "/" : "") + item.WebPath,
                        path = (isFirst ? "/" : "") + item.WebPath,
                        meta = new MetaClass()
                        {
                            title = item.SysPowerName
                        },
                        children = Build(children, allPowerList, false)
                    };
                    if (jsonMeta != null)
                    {
                        route.meta.ExCopyFrom(jsonMeta, "title");
                    }
                    r.Add(route);
                }
                return r;
            }
        }

        /// <summary>
        /// 按钮权限类
        /// </summary>
        public class ButtonPowerClass
        {
            /// <summary>
            /// 具体按钮
            /// </summary>
            public class ButtonPowerSonClass
            {
                /// <summary>
                /// 与页面的ref一样的值
                /// </summary>
                public string ButtonName { get; set; }

                /// <summary>
                /// 是否在操作列表里
                /// </summary>
                public bool IsInOp { get; set; }

                /// <summary>
                /// 是否有此权限
                /// </summary>
                public bool Has { get; set; }
            }

            /// <summary>
            /// 页面全路径,带上父级的
            /// </summary>
            public string Path { get; set; }

            /// <summary>
            /// 按钮信息
            /// </summary>
            public List<ButtonPowerSonClass> ButtonPowerSon { get; set; }

            internal static List<ButtonPowerClass> Build(List<SysPower> powerList, List<SysPower> allSysPower)
            {
                List<ButtonPowerClass> r = new List<ButtonPowerClass>();
                var list = powerList.Where(m => m.EnumPowerType == EnumPowerType.按钮 && m.ParentID != null).GroupBy(m => m.ParentID).ToList();
                foreach (IGrouping<int?, SysPower> item in list)
                {
                    string path = GetPath(item.Key, powerList);
                    ButtonPowerClass buttonPower = new ButtonPowerClass()
                    {
                        Path = path,
                        ButtonPowerSon = BuildButtonPowerSon(item, allSysPower)
                    };
                    r.Add(buttonPower);
                }
                return r;
            }

            private static List<ButtonPowerSonClass> BuildButtonPowerSon(IGrouping<int?, SysPower> item, List<SysPower> allSysPower)
            {
                List<ButtonPowerSonClass> list = new List<ButtonPowerSonClass>();
                var buttons = allSysPower.Where(m => m.ParentID == item.Key);
                foreach (var m in buttons)
                {
                    if (string.IsNullOrEmpty(m.SysPowerName)) continue;
                    var arr = m.SysPowerName.Split(StringExtentions.Split);
                    foreach (var buttonName in arr)
                    {
                        var tempButton = new ButtonPowerSonClass()
                        {
                            ButtonName = buttonName,
                            IsInOp = m.IsInOp,
                            Has = item.Any(n => n.SysPowerID == m.SysPowerID) //是否有此权限
                        };
                        list.Add(tempButton);
                    }
                }
                return list;
            }

            private static string GetPath(int? parentID, List<SysPower> powerList)
            {
                if (parentID == null)
                {
                    return string.Empty;
                }
                var current = powerList.FirstOrDefault(m => m.SysPowerID == parentID);
                string webPath = current.WebPath;
                string prefix = GetPath(current.ParentID, powerList);
                string r = (!string.IsNullOrEmpty(prefix) ? ((prefix[0] == '/' ? string.Empty : "/") + prefix) : string.Empty) + "/" + webPath;
                return r;
            }
        }

        #endregion

        /// <summary>
        /// token信息
        /// </summary>
        public string Token { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 头像
        /// </summary>
        public string UserHeader { get; set; }

        /// <summary>
        /// 权限菜单
        /// </summary>
        public List<RouteClass> Route { get; set; }

        /// <summary>
        /// 按钮权限
        /// </summary>
        public List<ButtonPowerClass> ButtonPower { get; set; }

        /// <summary>
        /// 是否能查看手机
        /// </summary>
        public bool CanSeePhone { get; set; }

        /// <summary>
        /// 是否管理员店铺
        /// </summary>
        public bool IsAdminStore { get; set; }

        /// <summary>
        /// 是否是主店铺
        /// </summary>
        public bool IsMainStore { get; set; }

        /// <summary>
        /// 店铺名称
        /// </summary>
        public string SysStoreName { get; set; }

        public string UserCode { get; set; }

        public int SysEmployeeID { get; set; }

        public int SysStoreID { get; set; }

        /// <summary>
        /// 是否试用帐号
        /// </summary>
        public bool IsDemo { get; set; }

        /// <summary>
        /// 创建事件
        /// </summary>
        public DateTime CreateDate { get; set; }
    }

    #endregion
}
